package com.epam.cdp.jpa.dao;

import java.util.List;

import javax.persistence.EntityManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.epam.cdp.jpa.model.BaseEntity;

/**
 * Class contains implementation of all common operations (CRUD) for DAO layer.
 *
 * Providing of entity manager and entity class is delegated to child classes. 
 * 
 * @author igor
 *
 */
public abstract class AbstractGenericDAO<T extends BaseEntity> implements GenericDAO<T> {

    private final static Log log = LogFactory.getLog(AbstractGenericDAO.class);

    public abstract EntityManager getEntityManager();

    public abstract Class<T> getEntityClass();
    
    @Override
    public void persist(T entity) {
	getEntityManager().persist(entity);
	log.debug("Successfully persited: " + entity);
    }

    @Override
    public void update(T entity) {
	log.debug("AbstractGenericDAO.update " + entity);
	getEntityManager().merge(entity);
    }

    @Override
    public T findById(long id) {
	T result = null;
	if (id > 0) {
	    result = getEntityManager().find(getEntityClass(), id);
	}
	return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> getAll() {
	StringBuilder query = new StringBuilder();
	query.append("SELECT e FROM ")
	     .append(getEntityClass().getSimpleName())
	     .append(" e");
	return getEntityManager().createQuery(query.toString()).getResultList();
    }

    @Override
    public void remove(T entity) {
	if (entity != null) {
	    remove(entity.getId());
	}

    }

    @Override
    public void remove(long id) {
	T entity = getEntityManager().find(getEntityClass(), id);
	    if (entity != null) {
		getEntityManager().remove(entity);
		log.debug("Successfully removed: " + entity);
	    }
    }


}
